﻿#include "tcprequester.h"
#include "widgettcpcfg.h"

TcpRequester::TcpRequester(QObject *parent) : BaseRequester(parent)
{
    _socket=new QTcpSocket();
    connect(_socket,&QTcpSocket::readyRead,this,&TcpRequester::onReadyReady);
    connect(_socket,  SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError1(QAbstractSocket::SocketError)));
}

TcpRequester::~TcpRequester()
{
    _socket->deleteLater();
}

bool TcpRequester::connectToHost()
{
    QString hostAddr=getCommParam();
    const QUrl url = QUrl::fromUserInput(hostAddr);
    _socket->connectToHost(url.host(),url.port());
    _socket->setSocketOption(QAbstractSocket::KeepAliveOption,1);
    return _socket->waitForConnected(1000);
}

bool TcpRequester::isConnected()
{
    return _socket->state()==QAbstractSocket::SocketState::ConnectedState;
}

bool TcpRequester::disConnect()
{
    _socket->disconnectFromHost();
    return true;
}

QByteArray TcpRequester::request(QByteArray data)
{
    _recList.clear();
    _socket->write(data);
    int timeout=_obj["timeout"].toInt();

    QElapsedTimer ela;
    ela.start();
    while(_recList.count()==0)
    {
        waitMs(20);
        if(ela.elapsed()>timeout)
        {
            throw QString("%1 time out").arg(getCommParam());
        }
    }

    waitMs(20);
    QByteArray arr;
    for(int i=0;i<_recList.count();i++)
    {
        arr.append(_recList.at(i));
    }
    return arr;
}

bool TcpRequester::requestNoReply(QByteArray data)
{
    int ret=_socket->write(data);
    _socket->waitForBytesWritten(100);

    bool isOk=ret!=data.size();
    if(!isOk)
    {
        qDebug()<<__FUNCTION__<<__LINE__<<"send err";
    }
    return isOk;
}

bool TcpRequester::requestImpl(QByteArray sendBuff, QByteArray &receiveBuff, int timeoutMs)
{
    QMutexLocker locker(&mutex);
    _socket->readAll();
    int ret=_socket->write(sendBuff);
    _socket->waitForBytesWritten(timeoutMs);
    if(ret!=sendBuff.size())
    {
        return false;
    }
    if(!_socket->waitForReadyRead(timeoutMs))
    {
        return false;
    }

    receiveBuff=_socket->readAll();
    return true;
}

QWidget *TcpRequester::getConfigWidget()
{
    WidgetTcpCfg *cfg=new WidgetTcpCfg();
    cfg->setComm(this);
    return cfg;
}

void TcpRequester::onReadyReady()
{
    QByteArray arr=_socket->readAll();
    _recList.append(arr);
}

void TcpRequester::onError1(QAbstractSocket::SocketError err)
{
    qDebug()<<__FUNCTION__<<_name<<"scoket error"<<err<<_socket->errorString();
}


void TcpRequester::waitMs(int ms)
{
    QEventLoop loop;
    QTimer::singleShot(ms, &loop, &QEventLoop::quit);  // 设置定时器，在超时时退出事件循环
    loop.exec();  // 进入事件循环
}
